﻿/*
Copyright (C) 2008 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

var g_securities = [];

var g_isDocked = true;

var g_versionChecker;
var VERSION_INFO_URL = 'http://desktop.google.com/plugins/versions/stocks.txt';

var g_isUpgradeMode = false;

function onOpen() {

  view.setTimeout(showNextRefreshTime, 1000)

  update();

  view.resizable = true;
  view.onminimize = onMinimize;
  view.onrestore = onRestore;
  view.onoptionchanged = onOptionChanged;
  view.onsize = onSize;
  view.onsizing = onSizing;
  view.ondock = onDock;
  view.onundock = onUndock;
  plugin.onAddCustomMenuItems = onMenuItems;

//this throws err in debug console...
//not registered so no version check:
//    g_versionChecker = new VersionChecker(strings.VERSION_STRING,
//      VERSION_INFO_URL, onMandatoryUpgrade);
}

function onMandatoryUpgrade(upgradeInfo) {
  debug.trace('Received mandatory upgrade notice.');

  g_isUpgradeMode = true;
  view.clearTimeout(g_refreshTimer);
  listbox.visible = false;
  plugin.onAddCustomMenuItems = null;

  upgradeReason.innerText = upgradeInfo.reason;
  upgradeInfoUrl.href = upgradeInfo.infoUrl;
  upgradeDownloadUrl.href = upgradeInfo.downloadUrl;
  upgradeDiv.visible = true;

  if (!g_isDocked) {
    UI.setUndockedHeight();
  }
}

function onMenuItems(menu) {
  menu.AddItem(strings.REFRESH, 0, update);
}

function onSize() {
  UI.resize();
}

function onSizing() {
  if (event.height < UI.MIN_HEIGHT) {
    event.height = UI.MIN_HEIGHT;
  }
}

function onOptionChanged() {
  if (event.propertyName == OPTIONS_IDS_KEY) {
        update();     
  }
}

function onDock() {
  g_isDocked = true;
  // We shortened the footer. Grippy won't fit anymore.
  grippy.visible = false;
  view.resizable = true;
}

function onUndock() {
  g_isDocked = false;
  view.width = UI.UNDOCKED_WIDTH;
  UI.setUndockedHeight();
  grippy.visible = false;
  view.resizable = false;
}

var g_minimizedTimer;
var g_minimizedIndex = 0;
var MINIMIZED_ROTATE_INTERVAL_MS = 5000;

function onMinimize() {
  updateCaption();
  view.clearInterval(g_minimizedTimer);
  g_minimizedTimer = view.setInterval(updateCaption,
      MINIMIZED_ROTATE_INTERVAL_MS);
}

function onRestore() {
  view.clearInterval(g_minimizedTimer);
  view.caption = strings.GADGET_NAME;
}

function onMouseOver() {
  optionsButton.visible = true;
}

function onMouseOut() {
  optionsButton.visible = false;
}

function updateCaption() {
  if (!g_securities.length) {
    return;
  }

  if (g_minimizedIndex >= g_securities.length) {
    g_minimizedIndex = 0;
  }

  var security = g_securities[g_minimizedIndex];
  view.caption = security.ticker +
      ' ' + Util.trimDecimalDigitsIfGe1000(security.last) +
      ' ' + security.change;

  ++g_minimizedIndex;
}

var g_refreshTimer = null;
var g_tryCount = 0;

var REFRESH_INTERVAL_MS = 30 * 1000;
var MAX_REFRESH_INTERVAL_MS = 90 * 1000;

var SetRefreshIntervalMS = REFRESH_INTERVAL_MS;

function scheduleImmediateRefresh() {


    if (REFRESH_INTERVAL_MS < SetRefreshIntervalMS) {
        SetRefreshIntervalMS -= 30000;
    }
    else {
        SetRefreshIntervalMS = SetRefreshIntervalMS - 5000;
    }

    if (SetRefreshIntervalMS < 5000) {
        SetRefreshIntervalMS = MAX_REFRESH_INTERVAL_MS;
    }

    nextRefreshSec = Math.round(SetRefreshIntervalMS / 1000);
    refreshLbl.innerText = nextRefreshSec;
    
    view.clearTimeout(g_refreshTimer);
    g_refreshTimer = view.setTimeout(update, SetRefreshIntervalMS);
}

var nextRefreshSec = 30;

function scheduleRefresh() {
  view.clearTimeout(g_refreshTimer);

  refreshLbl.innerText = "="; 

  var nextRetryMs;

      if (g_tryCount === 0) {
          nextRetryMs = SetRefreshIntervalMS;
      } else if (g_tryCount == 1) {
        nextRetryMs = SetRefreshIntervalMS * 2;
      } else if (g_tryCount == 2) {
        nextRetryMs = SetRefreshIntervalMS * 4;
      } else {
          nextRetryMs = MAX_REFRESH_INTERVAL_MS;
      }

      if (nextRetryMs > MAX_REFRESH_INTERVAL_MS) {
          nextRetryMs = MAX_REFRESH_INTERVAL_MS;
      }
  
  // A dash of randomness.
/*
  var jitter = 60 * 1000;
  jitter *= Math.random();
  jitter = Math.floor(jitter);

  nextRetryMs += jitter;
*/

  nextRefreshSec = Math.round(nextRetryMs / 1000);
  debug.trace('Retry request in ' + nextRetryMs);
  g_refreshTimer = view.setTimeout(update, nextRetryMs);
  ++g_tryCount;
  
  
}

function showNextRefreshTime() {

    var prob = "";
    if (g_tryCount > 1) {
        prob = "  :( " + (g_tryCount - 1);
    
    }

    if (refreshLbl.innerText != "***") {
        refreshLbl.innerText = "rfrsh (" + --nextRefreshSec + ")" + prob;
    }
    view.setTimeout(showNextRefreshTime, 1000);

}

function update() {
  if (g_isUpgradeMode) {
    return;
  }

  if (Util.isOnline()) {

      refreshLbl.innerText = "***";

      //pad with extra index to avoid bug of last item being removed if indexes are at bottom of list and some other unknown scenarios...
      //for some reason, on startup it isn't an issue????
        //yes, this is bad
    requestData(getIds(false) + '|.NYA,.NYA,0,0',  processData);
  } else {
    g_tryCount = 0;
  }
  scheduleRefresh();
}

//test what's so slow here, but we know its the sync web call
//the data call takes about 10 secs :(
function dontProcessData(obj)
{ }

function processDataFail(obj)
{
		debug.trace('process data call failure');
		debug.trace(obj);
}

function processData(securities) {

    var ids = getIds(false).split('|');

    //remove .INX from expected since its a padding value:
    for (key in ids) {
        if (ids[key].indexOf('.INX,') == 0) {
            ids.splice(key, 1);
        }
    }

    var expected = ids.length;


    securities = removeDupData(securities);
    
    
    //todo:  remove duplicates (created by padding values)

    var rec = securities.length;

    if (rec < expected) {
        debugger;
        
        var msg = '*** security receive count low :(   received: ' + rec + '  but expecting ' + expected;
        debug.trace(msg);
        alert(msg);
        
        update();
        return;
    }

	debug.trace('securities received');

  g_tryCount = 0;
  g_securities = securities;
  UI.draw(g_securities);
}

var g_detailsViewSecurity;

function openDetails(security) {
  if (g_detailsViewSecurity == security) {
    plugin.CloseDetailsView();
    g_detailsViewSecurity = null;
  } else {
    DetailsViewController.showDetailsView(security);
    g_detailsViewSecurity = security;
  }
}

function openInBrowser(id) {
  Util.openBrowser(URL_FINANCE + encodeURIComponent(id));
}

//could use an easy way to reset the ids
//could do it from the heading...  before first response...
function getIds(forceReset) {
  var ids = options.getValue(OPTIONS_IDS_KEY);

	debug.trace('Option ids: ' + ids);

	if (!ids || forceReset) {			// || true		//reload defaults
	    alert('resetting options to defaults');
    ids = strings.DEFAULT_SECURITIES;
    options.putValue(OPTIONS_IDS_KEY, ids);

		debug.trace('using default ids: ' + ids);
  }

  return ids;
}
